package com.zhb.cloud.login.controller;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.google.code.kaptcha.Constants;
import com.zhb.cloud.constants.SessionConstants;
import com.zhb.cloud.core.utils.CaptchaToken;
import com.zhb.cloud.core.utils.CookieUtils;
import com.zhb.cloud.core.utils.EncryptionUtils;
import com.zhb.cloud.core.utils.JsonReturn;
import com.zhb.cloud.mybatis.sys.service.UserService;

import lombok.Getter;
import lombok.Setter;

@RestController
@RequestMapping("/")
public class LoginController extends FormAuthenticationFilter {
	Logger log = LoggerFactory.getLogger(LoginController.class);
	// 相当于扩展了FormAuthenticationFilter
	public static final String DEFAULT_CAPTCHA_PARAM = "captcha";
	@Getter
	@Setter
	private String captchaParam = DEFAULT_CAPTCHA_PARAM;
	@Autowired
	private UserService userService;

	@RequestMapping(value = "login", method = RequestMethod.POST)
	public JsonReturn login(@RequestParam(name = "userName") String userName,
			@RequestParam(name = "password") String password, HttpServletRequest request,
			HttpServletResponse response) {
		JsonReturn jsonReturn = new JsonReturn();
		// 使用shiro 进行权限控制
		Subject userSubject = SecurityUtils.getSubject();
		if (StringUtils.isEmpty(userName)) {
			jsonReturn.setRetcode("400");
			jsonReturn.setRetmsg("用户名不能为空!");
			return jsonReturn;
		}
		if (StringUtils.isEmpty(password)) {
			jsonReturn.setRetcode("400");
			jsonReturn.setRetmsg("密码不能为空!");
			return jsonReturn;
		}
		// 将用户名和密码 封装成 令牌
		// 方法密码 必须 传递 char[]
		UsernamePasswordToken token = new UsernamePasswordToken(userName,
				EncryptionUtils.getEncryptionPassword(password).toCharArray());
		// 验证码tocken
		CaptchaToken captchaTokentoken = createToken(request, response);
		/* 图形验证码验证 */
		String captcha = getCaptchaFromSession(request, captchaTokentoken);
		// 比对
		if (StringUtils.isEmpty(captchaTokentoken.getCaptcha())) {
			jsonReturn.setRetcode("400");
			jsonReturn.setRetmsg("验证码不能为空!");
			return jsonReturn;
		}
		if (!captcha.equalsIgnoreCase(captchaTokentoken.getCaptcha())) {
			jsonReturn.setRetcode("400");
			jsonReturn.setRetmsg("验证码错误!");
			return jsonReturn;
		}
		// 记住用户信息,设置记住用户信息--默认是不记住
		token.setRememberMe(true);
		try {
			// shiro 提供登陆方法
			userSubject.login(token);
			// 生成ticket
			String ticket = userService.login(userName, password);
			// 把ticket保存到cookie中
			CookieUtils.setCookie(request, response, SessionConstants.USER_TICKET+userName, ticket, true);
			request.getSession().setAttribute("userName", userName);
			jsonReturn.setRetcode("200");
			jsonReturn.setRetmsg("登录成功!");
		} catch (UnknownAccountException e) {
			e.printStackTrace();
			jsonReturn.setRetcode("400");
			jsonReturn.setRetmsg("账户或密码错误!");
		} catch (IncorrectCredentialsException e) {
			e.printStackTrace();
			jsonReturn.setRetcode("400");
			jsonReturn.setRetmsg("账户或密码错误!");
		}
		return jsonReturn;
	}

	// 验证码校验
	protected String getCaptchaFromSession(HttpServletRequest request, CaptchaToken token) {
		// session中的图形码字符串
		return (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
	}

	/**
	 * 退出系统
	 * 
	 * @return
	 */
	@RequestMapping("logout")
	public ModelAndView logout(HttpServletRequest request) {
		// 通知Subject 已经退出系统
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
		// 销毁当前Session对象
		request.getSession().invalidate();
		return new ModelAndView("login");
	}

	@Override
	protected CaptchaToken createToken(ServletRequest request, ServletResponse response) {
		String captcha = getCaptcha(request);
		return new CaptchaToken(captcha);
	}

	protected String getCaptcha(ServletRequest request) {
		return WebUtils.getCleanParam(request, getCaptchaParam());
	}
}
